// Jocara game project

#include "miscellaneous.h"

SDL_Surface* kData[4];
TTF_Font* kFontSmall;
TTF_Font* kFontNormal;
TTF_Font* kFontBig;

SDL_Surface* LoadImage(const std::string name, const bool alpha) {
  std::string path = "data/" + name;
  SDL_Surface* loaded_image;
  SDL_Surface* result_image;
  loaded_image = IMG_Load(path.c_str());
  if(alpha) result_image = SDL_DisplayFormatAlpha(loaded_image);
  else result_image = SDL_DisplayFormat(loaded_image);
  SDL_FreeSurface(loaded_image);
  return result_image;
}

SDL_Surface* ScaleImage(SDL_Surface* surface, const unsigned int x,
                        const unsigned int y) {
  SDL_Surface* scaled_image;
  scaled_image = zoomSurface(surface, static_cast<double>(x) / surface->w,
                             static_cast<double>(y) / surface->h,
                             SMOOTHING_ON);
  return scaled_image;
}

void AlphaBlit(SDL_Surface* src, SDL_Rect* src_clip, SDL_Surface* dst,
               SDL_Rect* dst_clip) {
  // Lock the surfaces
  SDL_LockSurface(dst);
  SDL_LockSurface(src);
  // Define clipping areas even if there are none
  SDL_Rect* src_clip_;
  if(src_clip != NULL) {
    src_clip_ = src_clip;
  } else {
    src_clip_ = new SDL_Rect();
    src_clip_->x = 0;
    src_clip_->y = 0;
    src_clip_->h = src->h;
    src_clip_->w = src->w;
  }
  SDL_Rect* dst_clip_;
  if(dst_clip != NULL) {
    dst_clip_ = dst_clip;
  } else {
    dst_clip_ = new SDL_Rect();
    dst_clip_->x = 0;
    dst_clip_->y = 0;
    //dst_clip_->h = dst->h;
    //dst_clip_->w = dst->w;
  }
  // The actual blitting
  for(int y = src_clip_->y; y < src->h && y - src_clip_->y < dst->h
      && y < src_clip_->h + src_clip_->y; ++y) {
    for(int x = src_clip_->x; x < src->w && x - src_clip_->x < dst->w
        && x < src_clip_->w + src_clip_->x; ++x) {
      unsigned int src_pos = y * src->w + x;
      unsigned int dst_pos =
        (y - src_clip_->y + dst_clip_->y) * dst->w +
        x + dst_clip_->x - src_clip_->x;
      // Alpha bytes
      uint8_t src_a = static_cast<uint8_t*> (src->pixels)[src_pos*4+3];
      uint8_t dst_a = static_cast<uint8_t*> (dst->pixels)[dst_pos*4+3];
      // If the destination is empty, we draw over it
      if(dst_a == 0) {
        static_cast<uint8_t*> (dst->pixels)[dst_pos*4+3] = src_a;
        /*for(int i = 0; i <= 2; ++i) {
          static_cast<uint8_t*> (dst->pixels)[dst_pos*4+i] =
            static_cast<uint8_t*> (src->pixels)[src_pos*4+i];
        }*/
        memcpy(&static_cast<uint8_t*> (dst->pixels)[dst_pos*4],
               &static_cast<uint8_t*> (src->pixels)[src_pos*4],3);
        // If not and we have something to draw, things will get complicated
      } else {
        float src_a_f = src_a / 255.;
        float dst_a_f = dst_a / 255.;
        static_cast<uint8_t*> (dst->pixels)[dst_pos*4+3] =
          floor((src_a_f + dst_a_f * (1 - src_a_f)) * 255 + 0.5);
        for(int i = 0; i <= 2; ++i) {
          static_cast<uint8_t*> (dst->pixels)[dst_pos*4+i] =
            floor(src_a_f * static_cast<uint8_t*> (src->pixels)[src_pos*4+i] +
                  static_cast<uint8_t*> (dst->pixels)[dst_pos*4+i]
                  * (1 - src_a_f) + 0.5);
        }
      }
    }
  }

// Unlock the surfaces and delete clippig areas
  SDL_UnlockSurface(dst);
  SDL_UnlockSurface(src);
  if(src_clip == NULL) {
    delete src_clip_;
  }
  if(dst_clip == NULL) {
    delete dst_clip_;
  }
}
